package com.unitymarvel.harmonyos.projects.findme;

import com.unitymarvel.harmonyos.projects.findme.common.DataService;
import com.unitymarvel.harmonyos.projects.findme.common.DistributedGameServices;
import com.unitymarvel.harmonyos.projects.findme.common.Tools;
import com.unitymarvel.harmonyos.projects.findme.slice.MainAbilitySlice;
import com.unitymarvel.harmonyos.projects.findme.slice.SettingsAbilitySlice;
import com.unitymarvel.harmonyos.projects.findme.widget.controller.*;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.FormBindingData;
import ohos.aafwk.ability.ProviderFormInfo;
import ohos.aafwk.content.Intent;
import ohos.bundle.IBundleManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.security.SystemPermission;
import ohos.utils.zson.ZSONObject;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
///////////////////////////////////////////////////
// 项目的详细实现过程：https://ke.qq.com/course/3677276?tuin=a22a65ce
// 关注微信公众号和B站，获取更多鸿蒙学习资源
// 微信公众号：极客起源
// B站：https://space.bilibili.com/477001733
//
// 作者:李宁（蒙娜丽宁）
//
// 版本: 1.0
// Copyright (C), 2001-2022, 李宁
// 程序被版权法保护
//
///////////////////////////////////////////////////
public class MainAbility extends Ability {
    public static final int DEFAULT_DIMENSION_2X2 = 2;
    public static final int DIMENSION_1X2 = 1;
    public static final int DIMENSION_2X4 = 3;
    public static final int DIMENSION_4X4 = 4;
    private static final int INVALID_FORM_ID = -1;
    private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x0, MainAbility.class.getName());
    private String topWidgetSlice;
    private static Thread gameThread;
    public static String randomChar = "";
    public static long gamePanelFormId;
    public static Map<Long, GameWidgetData> gameWidgetFormIds = new HashMap<>();
    public static boolean startFlag;
    public static DataService dataService;
    private static Thread countDownThread;
    private static int countDown = SettingsAbilitySlice.countDown;

    public static int score = 0;
    public static DistributedGameServices distributedGameServices;
    private void requestPermission() {
        if (verifySelfPermission(SystemPermission.DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
            requestPermissionsFromUser(new String[] {SystemPermission.DISTRIBUTED_DATASYNC}, 0);
        }
    }
    public static class GameWidgetData {
        public String leftValue = "4";
        public String rightValue = "6";

        public String leftBackgroundColor = "#FF0000";
        public String rightBackgroundColor = "#FF00FF";

        public String leftColor = "#FF00FF";
        public String rightColor = "#FF0000";

    }
    public String getRandomChar() {
        String a = "0123456789qwert$yuiopasdfghjkl&zxcvbn@mABCDEFG%HIJKLMNO+PQRSTUVWXYZ";
        int rand = (int) (Math.random() * a.length());
        return String.valueOf(a.charAt(rand));

    }
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        requestPermission();
        if(distributedGameServices == null) {
            distributedGameServices = new DistributedGameServices(this);
            distributedGameServices.startServer();
        }
        if(dataService == null) {
            dataService = new DataService(this);
        }
        if (gameThread == null) {
            gameThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    List<String> randomChars = new ArrayList<>();
                    // 检测当前设备是否处于受控制状态
                    while (true) {
                        try {
                            Thread.sleep(50);
                            if (startFlag && DeviceListAbility.clientSocket == null) {


                                randomChars.clear();
                                int gameWidgetCount = gameWidgetFormIds.size();
                                if(DistributedGameServices.deviceDataMap.size() > 0) {
                                    try {
                                        getUITaskDispatcher().asyncDispatch(new Runnable() {
                                            @Override
                                            public void run() {
                                                //  Tools.showTip(MainAbility.this, "有客户端设备");
                                            }
                                        });
                                        String deviceRandomChars = "";
                                        for (DistributedGameServices.DeviceData deviceData : DistributedGameServices.deviceDataMap.values()) {
                                            for(int i = 0; i < deviceData.widgetCount * 2;i++) {
                                                String c = getRandomChar();
                                                deviceRandomChars += c;
                                                randomChars.add(c);
                                            }
                                            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(deviceData.socket.getOutputStream(), StandardCharsets.UTF_8));
                                            writer.write( "random_chars:" + deviceRandomChars + "\n");
                                            writer.flush();
                                            final  String s = deviceRandomChars;
                                            getUITaskDispatcher().asyncDispatch(new Runnable() {
                                                @Override
                                                public void run() {
                                                    //   Tools.showTip(MainAbility.this, "aa:" + s);

                                                }

                                            });
                                        }
                                    }catch (Exception e) {

                                    }
                                }

                                // 为每一张1*2卡片产生一个随机数
                                for (GameWidgetData gameWidgetData : gameWidgetFormIds.values()) {

                                    gameWidgetData.leftValue = getRandomChar();
                                    gameWidgetData.rightValue = getRandomChar();
                                    randomChars.add(gameWidgetData.leftValue);
                                    randomChars.add(gameWidgetData.rightValue);
                                    String[] colors = Tools.getTwoRandomHexColor();


                                    gameWidgetData.leftBackgroundColor = colors[0];
                                    gameWidgetData.leftColor = colors[1];

                                    colors = Tools.getTwoRandomHexColor();
                                    gameWidgetData.rightBackgroundColor = colors[0];
                                    gameWidgetData.rightColor = colors[1];
                                }

                                ZSONObject zsonObject = new ZSONObject();
                                // randomChar = getRandomChar();
                                int randomIndex = (int) (Math.random() *  randomChars.size());
                                randomChar = randomChars.get(randomIndex);

                                zsonObject.put("randomChar", randomChar);
                                distributedGameServices.write("random_char:" + randomChar);
                                FormBindingData formBindingData = new FormBindingData(zsonObject);
                                updateForm(gamePanelFormId, formBindingData);

                                // 更新1*2卡片上的数据
                                for (long gameWidgetFormId : gameWidgetFormIds.keySet()) {
                                    GameWidgetData gameWidgetData = gameWidgetFormIds.get(gameWidgetFormId);
                                    zsonObject = new ZSONObject();
                                    zsonObject.put("leftValue", gameWidgetData.leftValue);
                                    zsonObject.put("rightValue", gameWidgetData.rightValue);
                                    zsonObject.put("backgroundColor1", gameWidgetData.leftBackgroundColor);
                                    zsonObject.put("backgroundColor2", gameWidgetData.rightBackgroundColor);
                                    zsonObject.put("color1", gameWidgetData.leftColor);
                                    zsonObject.put("color2", gameWidgetData.rightColor);

                                    formBindingData = new FormBindingData(zsonObject);
                                    updateForm(gameWidgetFormId, formBindingData);

                                }
                                Thread.sleep(SettingsAbilitySlice.randomInterval);
                            }
                        } catch (Exception e) {

                            System.out.println(e.getMessage());
                            startFlag = false;
                        }

                    }
                }
            });
            gameThread.start();
        }
        if (countDownThread == null) {
            countDownThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            Thread.sleep(100);
                            if (startFlag) {
                                if(countDown > 0) {
                                    updateWidget(gamePanelFormId, "countDown", countDown);
                                    Thread.sleep(1000);
                                    countDown--;
                                }  else {  // 等于0
                                    updateWidget(gamePanelFormId, "countDown", countDown);
                                    dataService.writeGameRecord(SettingsAbilitySlice.user, score);
                                    startFlag = false;
                                    countDown = SettingsAbilitySlice.countDown;;

                                    getMainTaskDispatcher().asyncDispatch(new Runnable() {
                                        @Override
                                        public void run() {

                                            Tools.showTip(MainAbility.this, "游戏结束，共获得" + score + "分");
                                            score = 0;


                                        }
                                    });
                                }
                            } else {
                                countDown = SettingsAbilitySlice.countDown;
                            }
                        } catch (Exception e) {


                        }
                    }


                }
            });
            countDownThread.start();
        }
    }
    private void updateWidget(long formId,String key, String value) {
        try {
            ZSONObject zsonObject = new ZSONObject();
            zsonObject.put(key, value);
            FormBindingData formBindingData = new FormBindingData(zsonObject);
            updateForm(formId, formBindingData);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    public void updateWidget(long formId,String key, int value) {
        updateWidget(formId, key, String.valueOf(value));

    }
    @Override
    protected ProviderFormInfo onCreateForm(Intent intent) {
        HiLog.info(TAG, "onCreateForm");
        long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
        String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
        int dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
        HiLog.info(TAG, "onCreateForm: formId=" + formId + ",formName=" + formName);
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        FormController formController = formControllerManager.getController(formId);
        formController = (formController == null) ? formControllerManager.createFormController(formId,
                formName, dimension) : formController;
        if (formController == null) {
            HiLog.error(TAG, "Get null controller. formId: " + formId + ", formName: " + formName);
            return null;
        }
        if (formName.equals("GameWidget")) {
            GameWidgetData gameWidgetData = new GameWidgetData();
            gameWidgetFormIds.put(formId, gameWidgetData);
        } else if (formName.equals("GamePanel")) {
            if (gamePanelFormId == 0) {
                // 如果控制游戏的Widget不存在，则保存Widget的formId
                gamePanelFormId = formId;
            }
        }
        return formController.bindFormData();
    }

    @Override
    protected void onUpdateForm(long formId) {
        HiLog.info(TAG, "onUpdateForm");
        super.onUpdateForm(formId);
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        FormController formController = formControllerManager.getController(formId);
        formController.updateFormData(formId);
    }

    @Override
    protected void onDeleteForm(long formId) {
        HiLog.info(TAG, "onDeleteForm: formId=" + formId);
        super.onDeleteForm(formId);
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        formControllerManager.deleteFormController(formId);
        // 如果删除了游戏控制Widget，则清除formId
        if (gamePanelFormId == formId) {
            gamePanelFormId = 0;
        } else {  // 当删除Game Widget时，清除对应的formId
            gameWidgetFormIds.remove(formId);
        }
    }


    @Override
    protected void onTriggerFormEvent(long formId, String message) {
        HiLog.info(TAG, "onTriggerFormEvent: " + message);
        super.onTriggerFormEvent(formId, message);
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        FormController formController = formControllerManager.getController(formId);
        formController.onTriggerFormEvent(formId, message);
        ZSONObject zsonObject = ZSONObject.stringToZSON(message);
        String msg = zsonObject.getString("message");
        if (msg.equals("start")) {
            getMainTaskDispatcher().asyncDispatch(new Runnable() {
                @Override
                public void run() {
                    System.out.println("start");
                    startFlag = true;
                    updateWidget(gamePanelFormId, "score", score);
                }
            });

        }else if (msg.equals("stop")) {
            startFlag = false;
            score = 0;
            countDown = SettingsAbilitySlice.countDown;
            updateWidget(gamePanelFormId, "countDown", countDown);
            updateWidget(gamePanelFormId, "score", score);
        } else {
            if(startFlag) {

                GameWidgetData gameWidgetData = gameWidgetFormIds.get(formId);

                if (gameWidgetData != null) {
                    String clickChar = "";
                    if (msg.equals("left")) {
                        clickChar = gameWidgetData.leftValue;
                    } else {
                        clickChar = gameWidgetData.rightValue;
                    }
                    if(DeviceListAbility.clientSocket == null) {
                        if (clickChar.equals(randomChar)) {
                            score += SettingsAbilitySlice.scoreIncrement;
                            updateWidget(gamePanelFormId, "score", score);
                        }

                    } else {
                        try {

                            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(DeviceListAbility.clientSocket.getOutputStream()));
                            //向服务器端发送一条消息
                            if(DeviceListAbility.serverRandomChar.equals(clickChar)) {
                                bw.write("score:\n");
                            }
                            // bw.write("click_char:" + clickChar);
                            bw.flush();
                            final String s = clickChar;



                        } catch (Exception e) {

                        }

                    }
                }

            }



        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        if (intentFromWidget(intent)) { // Only response to it when starting from a service widget.
            String newWidgetSlice = getRoutePageSlice(intent);
            if (topWidgetSlice == null || !topWidgetSlice.equals(newWidgetSlice)) {
                topWidgetSlice = newWidgetSlice;
                restart();
            }
        }
    }

    private boolean intentFromWidget(Intent intent) {
        long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
        return formId != INVALID_FORM_ID;
    }

    private String getRoutePageSlice(Intent intent) {
        long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
        if (formId == INVALID_FORM_ID) {
            return null;
        }
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        FormController formController = formControllerManager.getController(formId);
        if (formController == null) {
            return null;
        }
        Class<? extends AbilitySlice> clazz = formController.getRoutePageSlice(intent);
        if (clazz == null) {
            return null;
        }
        return clazz.getName();
    }
}
